﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

//Task 5 - Define a class BitArray64 to hold 64 bit values inside an ulong value. 
//Implement IEnumerable<int> and Equals(…), GetHashCode(), [], == and !=.

namespace _BitArray64
{
    public class BitArray64 : IEnumerable<int>
    {
        private ulong number;
        public ulong Number
        {
            get { return number; }
            set
            {
                if (value < 0 || value > 18446744073709551615)
                {
                    throw new ArgumentException("Invalid input!!!");
                }
                else
                {
                    number = value;
                }
            }
        }
        public BitArray64(ulong number)
        {
            this.Number = number;
        }
        public override bool Equals(object obj)
        {
            var numberToCompare = obj as BitArray64;

            if (numberToCompare == null)
            {
                return false;
            }


            if (!Object.Equals(this.Number, numberToCompare.Number))
            {
                return false;
            }
            return true;
        }
        public static bool operator ==(BitArray64 a, BitArray64 b)
        {
            return BitArray64.Equals(a, b);
        }


        public static bool operator !=(BitArray64 a, BitArray64 b)
        {
            return !BitArray64.Equals(a, b);
        }

        public override int GetHashCode()
        {
            //Just some expression that I thought. Bet there is better way... 
            return (int)(this.Number % 100000000) ^ int.MaxValue;
        }

        protected int[] ConvertedToBinary()
        {
            var numberToConvert = this.Number;
            var bits = new int[64];
            int index = 63;
            {
                while (numberToConvert >= 1)
                {
                    //From this cast, numbers larger than int.MaxValue are shown wrongly
                    int divisionByTwo = (int)numberToConvert % 2;
                    if (divisionByTwo == -1)
                    {
                        bits[index] = 1;
                    }
                    else
                    {
                        bits[index] = divisionByTwo;
                    }
                    numberToConvert /= 2;
                    index--;
                }
            }
            return bits;
        }
        public IEnumerator<int> GetEnumerator()
        {
            int[] bits = ConvertedToBinary();
            for (int i = 0; i < bits.Length; i++)
            {
                yield return bits[i];
            }
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
    }
}

